<!DOCTYPE html>
<html>
    
<head>
    <meta charset="utf-8">
    
    <title>100 行 js 代码下载抖音无水印视频 | ApocalypseBlog</title>
    <canvas id="header_canvas"style="position:absolute;bottom:0"></canvas> 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    

    

    

    

    
<link rel="stylesheet" href="/dist/build.css?v=1.14.0.css">

    <script src="/javascripts/bubble.js"></script>
    <script>
        window.isPost = true
        window.aomori = {
            
            
        }
        window.aomori_logo_typed_animated = false
        window.aomori_search_algolia = false

    </script>
<script>
    ((window.gitter = {}).chat = {}).options = {
      room: 'ApocalypseBlog/Apocalypse'
    };
  </script>
  <script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer></script>
<meta name="generator" content="Hexo 5.3.0"></head>
<!--DaoVoice服务http://blog.daovoice.io/-->

    <script>(function (i, s, o, g, r, a, m) {
        i['DaoVoiceObject'] = r;
        i[r] = i[r] ||
          function () {
            (i[r].q = i[r].q || []).push(arguments);
          };
        i[r].l = 1 * new Date();
        a = s.createElement(o);
        m = s.getElementsByTagName(o)[0];
        a.async = 1;
        a.src = g;
        a.charset = 'utf-8';
        m.parentNode.insertBefore(a, m);
      })(window, document, 'script', ('https:' === document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/b00f5052.js", 'daovoice');
      daovoice('init', {
        app_id: "b00f5052",
      });
      daovoice('update');
    </script>
  
<body>

    <div class="container">
    <header class="header">
        <div class="header-type">
            
            <div class="header-type-inner">
                
                    <a class="header-type-title" href="/">ApocalypseBlog</a>
                
    
                
            </div>
        </div>
        <div class="header-menu">
            <div class="header-menu-inner">
                
            </div>
            <div class="header-menu-social">
                
            </div>
        </div>

        <div class="header-menu-mobile">
            <div class="header-menu-mobile-inner" id="mobile-menu-open">
                <i class="icon icon-menu"></i>
            </div>
        </div>
    </header>

    <div class="header-menu-mobile-menu">
        <div class="header-menu-mobile-menu-bg"></div>
        <div class="header-menu-mobile-menu-wrap">
            <div class="header-menu-mobile-menu-inner">
                <div class="header-menu-mobile-menu-close" id="mobile-menu-close">
                    <i class="icon icon-cross"></i>
                </div>
                <div class="header-menu-mobile-menu-list">
                    
                </div>
            </div>
        </div>
    </div>

</div>

    <div class="container">
        <div class="main">
            <section class="inner">
                <section class="inner-main">
                    <div class="post">
    <article id="post-ckk6o6auc00017kny8dfuaw1i" class="article article-type-post" itemscope
    itemprop="blogPost">

    <div class="article-inner">

        
          
        
        
        

        
        <header class="article-header">
            
  
    <h1 class="article-title" itemprop="name">
      100 行 js 代码下载抖音无水印视频
    </h1>
  

        </header>
        

        <div class="article-more-info article-more-info-post hairline">

            <div class="article-date">
  <time datetime="2020-06-15T22:18:29.000Z" itemprop="datePublished">2020-06-16</time>
</div>

            

            

            

        </div>

        <div class="article-entry post-inner-html hairline" itemprop="articleBody">
            <blockquote>
<p>本文大约 600 字，看完本文大概需要 5 分钟，仅供学习使用，如有错误，请指正。</p>
</blockquote>
<h3 id="需求"><a href="#需求" class="headerlink" title="需求"></a>需求</h3><p>抖音平台下载一个视频，去掉左上角的水印id。</p>
<h3 id="先来看看有水印效果"><a href="#先来看看有水印效果" class="headerlink" title="先来看看有水印效果"></a>先来看看有水印效果</h3><p>这时候就会发现，抖音官方下载下来的视频，会有抖音的水印，需要去掉水印。</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/13/172ae574b9c8c350?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<a id="more"></a>

<h3 id="分享视频"><a href="#分享视频" class="headerlink" title="分享视频"></a>分享视频</h3><p>从抖音分享一个视频，你会获得一个分享文案和地址，格式如下（不懂怎么分享可以百度）</p>
<pre><code>一只都放不明白 https://v.douyin.com/JdbBqog/ 复制此链接，打开【抖音短视频】，直接观看视频！</code></pre>
<p><strong>把上面的 url 地址 ( <a target="_blank" rel="noopener" href="https://v.douyin.com/JdbBqog/">v.douyin.com/JdbBqog/</a>) 放到浏览器模拟的手机模式下看看发生了什么</strong></p>
<h3 id="1-重定向"><a href="#1-重定向" class="headerlink" title="1. 重定向"></a>1. 重定向</h3><p>短地址会重定向，</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/13/172ae50b922c908e?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p>访问这个重定向的地址获取两个重要的参数</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/13/172ae5fe6f37221f?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<h3 id="2-一个关键的-ajax"><a href="#2-一个关键的-ajax" class="headerlink" title="2. 一个关键的 ajax"></a>2. 一个关键的 ajax</h3><p>利用上面 html 内嵌 script 获取的两个参数，请求下面的地址。</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/13/172ae5ec81b4f832?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p>请求返回了一个 json 包含了这个视频的一些信息，其中有一个去水印的关键参数 <strong>uri</strong></p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/14/172ae6ac3594fdbf?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p>到这里，抖音官方的流程就走完了。</p>
<h3 id="3-如何去水印？"><a href="#3-如何去水印？" class="headerlink" title="3. 如何去水印？"></a>3. 如何去水印？</h3><p>原理：并不是用高大上的人工智障或者类似 ps 去掉某一个地方的水印，而是抖音会保存一份无水印的视频，我们只需要找到这个无水印视频的地址就可以了。</p>
<p>说完原理，实现就是根据上面获取的字段 uri ,然后拼接在一个抖音存储无水印视频的地址上就完事了。（这个拼接的地址在浏览器上可能访问不了） 看代码吧</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/14/172ae6c25f269dbd?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<h3 id="实现效果"><a href="#实现效果" class="headerlink" title="实现效果"></a>实现效果</h3><p><img src="http://user-gold-cdn.xitu.io/2020/6/13/172ae675ad0c304e?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<h3 id="node-js-代码仓库"><a href="#node-js-代码仓库" class="headerlink" title="node.js 代码仓库"></a>node.js 代码仓库</h3><p><a target="_blank" rel="noopener" href="https://github.com/Faithree/dy">代码仓库</a> <strong>仅供学习使用</strong></p>
<p>分两种下载模式，浏览器下载和命令行下载</p>
<ol>
<li>浏览器输入即可下载 (方便提供接口)</li>
</ol>
<pre><code class="vbscript">npm start 
or 
node index</code></pre>
<p>使用</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/14/172ae75aa19e3a88?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p>代码</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/14/172ae7ab72cac233?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<ol>
<li>工具模式下载到目录(类似命令行工具)</li>
</ol>
<pre><code>node tool</code></pre>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/14/172ae78631765b7d?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a target="_blank" rel="noopener" href="https://mp.weixin.qq.com/s/DF7_b_F1iHUqPnOqYV3uYA">mp.weixin.qq.com/s/DF7_b_F1i…</a></p>
<p><a target="_blank" rel="noopener" href="https://gitee.com/goldriver/douyin">gitee.com/goldriver/d…</a></p>

        </div>

    </div>

    

    

    

    

    

    
<nav class="article-nav">
  
    <a href="/2020/06/16/FragmentStatePagerAdapter%E5%9C%A8ViewPager%E4%B8%AD%E4%BC%98%E5%8C%96%E4%BA%86%E4%BB%80%E4%B9%88/" id="article-nav-newer" class="article-nav-link-wrap">
      <div class="article-nav-caption">下一篇</div>
      <div class="article-nav-title">
        
          FragmentStatePagerAdapter在ViewPager中优化了什么
        
      </div>
    </a>
  
  
    <a href="/2020/06/14/Kotlin%E4%B8%8EJava%E7%9A%84%E5%BC%82%E5%90%8C/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-caption">上一篇</div>
      <div class="article-nav-title">Kotlin与Java的异同</div>
    </a>
  
</nav>


    <section class="share">
        <div class="share-title">分享</div>
        <a class="share-item" target="_blank"
            href="https://twitter.com/share?text=100 行 js 代码下载抖音无水印视频 - ApocalypseBlog&url=http://example.com/2020/06/16/100%E8%A1%8Cjs%E4%BB%A3%E7%A0%81%E4%B8%8B%E8%BD%BD%E6%8A%96%E9%9F%B3%E6%97%A0%E6%B0%B4%E5%8D%B0%E8%A7%86%E9%A2%91/">
            <box-icon type='logo' name='twitter'></box-icon>
        </a>
        <a class="share-item" target="_blank"
            href="https://www.facebook.com/sharer.php?title=100 行 js 代码下载抖音无水印视频 - ApocalypseBlog&u=http://example.com/2020/06/16/100%E8%A1%8Cjs%E4%BB%A3%E7%A0%81%E4%B8%8B%E8%BD%BD%E6%8A%96%E9%9F%B3%E6%97%A0%E6%B0%B4%E5%8D%B0%E8%A7%86%E9%A2%91/">
            <box-icon name='facebook-square' type='logo' ></box-icon>
        </a>
        <!-- <a class="share-item" target="_blank"
            href="https://service.weibo.com/share/share.php?title=100 行 js 代码下载抖音无水印视频 - ApocalypseBlog&url=http://example.com/2020/06/16/100%E8%A1%8Cjs%E4%BB%A3%E7%A0%81%E4%B8%8B%E8%BD%BD%E6%8A%96%E9%9F%B3%E6%97%A0%E6%B0%B4%E5%8D%B0%E8%A7%86%E9%A2%91/&pic=">
            <div class="n-icon n-icon-weibo"></div>
        </a> -->
    </section>

</article>









</div>
                </section>
            </section>

             
            <aside class="sidebar">
            
                
            </aside>
        </div>
    </div>

    <footer class="footer">
    <div class="footer-wave">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#3c4859" fill-opacity="1" d="M0,160L60,181.3C120,203,240,245,360,240C480,235,600,181,720,186.7C840,192,960,256,1080,261.3C1200,267,1320,213,1380,186.7L1440,160L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path></svg>
    </div>

    <div class="footer-wrap">
        <div class="footer-inner"> 
            ApocalypseBlog &copy; 2021<br>
            Powered By Hexo · Theme By <a href="https://github.com/lh1me/hexo-theme-aomori" target="_blank">Aomori</a>
        </div>
    </div>

</footer>




<script src="/dist/build.js?1.14.0.js"></script>


<script src="/dist/custom.js?1.14.0.js"></script>









</body>

</html>